home *** CD-ROM | disk | FTP | other *** search
/ MacGames Sampler / PHT MacGames Bundle.iso / MacSource Folder / Samples from the CD / C and C++ / Gnuplot 3.5 for Macintosh / SOURCES 3.5 / internal.c < prev    next >
Text File  |  1993-11-12  |  17KB  |  896 lines

  1. #ifndef lint
  2. static char *RCSid = "$Id: internal.c%v 3.50.1.8 1993/07/27 05:37:15 woo Exp $";
  3. #endif
  4.  
  5.  
  6. /* GNUPLOT - internal.c */
  7. /*
  8.  * Copyright (C) 1986 - 1993   Thomas Williams, Colin Kelley
  9.  *
  10.  * Permission to use, copy, and distribute this software and its
  11.  * documentation for any purpose with or without fee is hereby granted, 
  12.  * provided that the above copyright notice appear in all copies and 
  13.  * that both that copyright notice and this permission notice appear 
  14.  * in supporting documentation.
  15.  *
  16.  * Permission to modify the software is granted, but not the right to
  17.  * distribute the modified code.  Modifications are to be distributed 
  18.  * as patches to released version.
  19.  *  
  20.  * This software is provided "as is" without express or implied warranty.
  21.  * 
  22.  *
  23.  * AUTHORS
  24.  * 
  25.  *   Original Software:
  26.  *     Thomas Williams,  Colin Kelley.
  27.  * 
  28.  *   Gnuplot 2.0 additions:
  29.  *       Russell Lang, Dave Kotz, John Campbell.
  30.  *
  31.  *   Gnuplot 3.0 additions:
  32.  *       Gershon Elber and many others.
  33.  * 
  34.  */
  35.  
  36. #include <math.h>
  37. #include <stdio.h>
  38. #include "plot.h"
  39. #ifdef THINK_C
  40. #include "tout_protos.h"
  41. #endif
  42.  
  43. TBOOLEAN undefined;
  44.  
  45. #ifndef AMIGA_SC_6_1
  46. char *strcpy();
  47. #endif /* !AMIGA_SC_6_1 */
  48.  
  49. struct value *pop(), *Gcomplex(), *Ginteger();
  50. double magnitude(), angle(), real();
  51.  
  52. struct value stack[STACK_DEPTH];
  53.  
  54. int s_p = -1;   /* stack pointer */
  55.  
  56.  
  57. /*
  58.  * System V and MSC 4.0 call this when they wants to print an error message.
  59.  * Don't!
  60.  */
  61. #ifndef _CRAY
  62. #if defined(MSDOS) || defined(DOS386)
  63. #ifdef __TURBOC__
  64. int matherr()    /* Turbo C */
  65. #else
  66. int matherr(x)    /* MSC 5.1 */
  67. struct exception *x;
  68. #endif /* TURBOC */
  69. #else /* not MSDOS */
  70. #ifdef apollo
  71. int matherr(struct exception *x)    /* apollo */
  72. #else /* apollo */
  73. #if defined(AMIGA_SC_6_1)||defined(ATARI)&&defined(__GNUC__)||defined(__hpux__)||defined(PLOSS) ||defined(SOLARIS)
  74. int matherr(x)
  75. struct exception *x;
  76. #else    /* Most everyone else (not apollo). */
  77. int matherr()
  78. #endif /* AMIGA_SC_6_1 || GCC_ST */
  79. #endif /* apollo */
  80. #endif /* MSDOS */
  81. {
  82.     return (undefined = TRUE);        /* don't print error message */
  83. }
  84. #endif /* not _CRAY */
  85.  
  86.  
  87. reset_stack()
  88. {
  89.     s_p = -1;
  90. }
  91.  
  92.  
  93. check_stack()    /* make sure stack's empty */
  94. {
  95.     if (s_p != -1)
  96.         fprintf(stderr,"\nwarning:  internal error--stack not empty!\n");
  97. }
  98.  
  99.  
  100. struct value *pop(x)
  101. struct value *x;
  102. {
  103.     if (s_p  < 0 )
  104.         int_error("stack underflow",NO_CARET);
  105.     *x = stack[s_p--];
  106.     return(x);
  107. }
  108.  
  109.  
  110. push(x)
  111. struct value *x;
  112. {
  113.     if (s_p == STACK_DEPTH - 1)
  114.         int_error("stack overflow",NO_CARET);
  115.     stack[++s_p] = *x;
  116. }
  117.  
  118.  
  119. #define ERR_VAR "undefined variable: "
  120.  
  121. f_push(x)
  122. union argument *x;        /* contains pointer to value to push; */
  123. {
  124. static char err_str[sizeof(ERR_VAR) + MAX_ID_LEN] = ERR_VAR;
  125. struct udvt_entry *udv;
  126.  
  127.     udv = x->udv_arg;
  128.     if (udv->udv_undef) {     /* undefined */
  129.         (void) strcpy(&err_str[sizeof(ERR_VAR) - 1], udv->udv_name);
  130.         int_error(err_str,NO_CARET);
  131.     }
  132.     push(&(udv->udv_value));
  133. }
  134.  
  135.  
  136. f_pushc(x)
  137. union argument *x;
  138. {
  139.     push(&(x->v_arg));
  140. }
  141.  
  142.  
  143. f_pushd1(x)
  144. union argument *x;
  145. {
  146.     push(&(x->udf_arg->dummy_values[0]));
  147. }
  148.  
  149.  
  150. f_pushd2(x)
  151. union argument *x;
  152. {
  153.     push(&(x->udf_arg->dummy_values[1]));
  154. }
  155.  
  156.  
  157. f_pushd(x)
  158. union argument *x;
  159. {
  160. struct value param;
  161.     (void) pop(¶m);
  162.     push(&(x->udf_arg->dummy_values[param.v.int_val]));
  163. }
  164.  
  165.  
  166. #define ERR_FUN "undefined function: "
  167.  
  168. f_call(x)  /* execute a udf */
  169. union argument *x;
  170. {
  171. static char err_str[sizeof(ERR_FUN) + MAX_ID_LEN] = ERR_FUN;
  172. register struct udft_entry *udf;
  173. struct value save_dummy;
  174.  
  175.     udf = x->udf_arg;
  176.     if (!udf->at) { /* undefined */
  177.         (void) strcpy(&err_str[sizeof(ERR_FUN) - 1],
  178.                 udf->udf_name);
  179.         int_error(err_str,NO_CARET);
  180.     }
  181.     save_dummy = udf->dummy_values[0];
  182.     (void) pop(&(udf->dummy_values[0]));
  183.  
  184.     execute_at(udf->at);
  185.     udf->dummy_values[0] = save_dummy;
  186. }
  187.  
  188.  
  189. f_calln(x)  /* execute a udf of n variables */
  190. union argument *x;
  191. {
  192. static char err_str[sizeof(ERR_FUN) + MAX_ID_LEN] = ERR_FUN;
  193. register struct udft_entry *udf;
  194. struct value save_dummy[MAX_NUM_VAR];
  195.  
  196.     int i;
  197.     int num_pop;
  198.     struct value num_params;
  199.  
  200.     udf = x->udf_arg;
  201.     if (!udf->at) { /* undefined */
  202.         (void) strcpy(&err_str[sizeof(ERR_FUN) - 1],
  203.                 udf->udf_name);
  204.         int_error(err_str,NO_CARET);
  205.     }
  206.     for(i=0; i<MAX_NUM_VAR; i++) 
  207.         save_dummy[i] = udf->dummy_values[i];
  208.  
  209.     /* if there are more parameters than the function is expecting */
  210.     /* simply ignore the excess */
  211.     (void) pop(&num_params);
  212.  
  213.     if(num_params.v.int_val > MAX_NUM_VAR) {
  214.         /* pop the dummies that there is no room for */
  215.         num_pop = num_params.v.int_val - MAX_NUM_VAR;
  216.         for(i=0; i< num_pop; i++)
  217.             (void) pop(&(udf->dummy_values[i]));
  218.  
  219.         num_pop = MAX_NUM_VAR;
  220.     } else {
  221.         num_pop = num_params.v.int_val;
  222.     }
  223.  
  224.     /* pop parameters we can use */
  225.     for(i=num_pop-1; i>=0; i--)
  226.         (void) pop(&(udf->dummy_values[i]));
  227.  
  228.     execute_at(udf->at);
  229.     for(i=0; i<MAX_NUM_VAR; i++) 
  230.         udf->dummy_values[i] = save_dummy[i];
  231. }
  232.  
  233.  
  234. static int_check(v)
  235. struct value *v;
  236. {
  237.     if (v->type != INTGR)
  238.         int_error("non-integer passed to boolean operator",NO_CARET);
  239. }
  240.  
  241.  
  242. f_lnot()
  243. {
  244. struct value a;
  245.     int_check(pop(&a));
  246.     push(Ginteger(&a,!a.v.int_val) );
  247. }
  248.  
  249.  
  250. f_bnot()
  251. {
  252. struct value a;
  253.     int_check(pop(&a));
  254.     push( Ginteger(&a,~a.v.int_val) );
  255. }
  256.  
  257.  
  258. f_bool()
  259. {            /* converts top-of-stack to boolean */
  260.     int_check(&top_of_stack);
  261.     top_of_stack.v.int_val = !!top_of_stack.v.int_val;
  262. }
  263.  
  264.  
  265. f_lor()
  266. {
  267. struct value a,b;
  268.     int_check(pop(&b));
  269.     int_check(pop(&a));
  270.     push( Ginteger(&a,a.v.int_val || b.v.int_val) );
  271. }
  272.  
  273. f_land()
  274. {
  275. struct value a,b;
  276.     int_check(pop(&b));
  277.     int_check(pop(&a));
  278.     push( Ginteger(&a,a.v.int_val && b.v.int_val) );
  279. }
  280.  
  281.  
  282. f_bor()
  283. {
  284. struct value a,b;
  285.     int_check(pop(&b));
  286.     int_check(pop(&a));
  287.     push( Ginteger(&a,a.v.int_val | b.v.int_val) );
  288. }
  289.  
  290.  
  291. f_xor()
  292. {
  293. struct value a,b;
  294.     int_check(pop(&b));
  295.     int_check(pop(&a));
  296.     push( Ginteger(&a,a.v.int_val ^ b.v.int_val) );
  297. }
  298.  
  299.  
  300. f_band()
  301. {
  302. struct value a,b;
  303.     int_check(pop(&b));
  304.     int_check(pop(&a));
  305.     push( Ginteger(&a,a.v.int_val & b.v.int_val) );
  306. }
  307.  
  308.  
  309. f_uminus()
  310. {
  311. struct value a;
  312.     (void) pop(&a);
  313.     switch(a.type) {
  314.         case INTGR:
  315.             a.v.int_val = -a.v.int_val;
  316.             break;
  317.         case CMPLX:
  318.             a.v.cmplx_val.real =
  319.                 -a.v.cmplx_val.real;
  320.             a.v.cmplx_val.imag =
  321.                 -a.v.cmplx_val.imag;
  322.     }
  323.     push(&a);
  324. }
  325.  
  326.  
  327. f_eq() /* note: floating point equality is rare because of roundoff error! */
  328. {
  329. struct value a, b;
  330.     register int result;
  331.     (void) pop(&b);
  332.     (void) pop(&a);
  333.     switch(a.type) {
  334.         case INTGR:
  335.             switch (b.type) {
  336.                 case INTGR:
  337.                     result = (a.v.int_val ==
  338.                         b.v.int_val);
  339.                     break;
  340.                 case CMPLX:
  341.                     result = (a.v.int_val ==
  342.                         b.v.cmplx_val.real &&
  343.                        b.v.cmplx_val.imag == 0.0);
  344.             }
  345.             break;
  346.         case CMPLX:
  347.             switch (b.type) {
  348.                 case INTGR:
  349.                     result = (b.v.int_val == a.v.cmplx_val.real &&
  350.                        a.v.cmplx_val.imag == 0.0);
  351.                     break;
  352.                 case CMPLX:
  353.                     result = (a.v.cmplx_val.real==
  354.                         b.v.cmplx_val.real &&
  355.                         a.v.cmplx_val.imag==
  356.                         b.v.cmplx_val.imag);
  357.             }
  358.     }
  359.     push(Ginteger(&a,result));
  360. }
  361.  
  362.  
  363. f_ne()
  364. {
  365. struct value a, b;
  366.     register int result;
  367.     (void) pop(&b);
  368.     (void) pop(&a);
  369.     switch(a.type) {
  370.         case INTGR:
  371.             switch (b.type) {
  372.                 case INTGR:
  373.                     result = (a.v.int_val !=
  374.                         b.v.int_val);
  375.                     break;
  376.                 case CMPLX:
  377.                     result = (a.v.int_val !=
  378.                         b.v.cmplx_val.real ||
  379.                        b.v.cmplx_val.imag != 0.0);
  380.             }
  381.             break;
  382.         case CMPLX:
  383.             switch (b.type) {
  384.                 case INTGR:
  385.                     result = (b.v.int_val !=
  386.                         a.v.cmplx_val.real ||
  387.                        a.v.cmplx_val.imag != 0.0);
  388.                     break;
  389.                 case CMPLX:
  390.                     result = (a.v.cmplx_val.real !=
  391.                         b.v.cmplx_val.real ||
  392.                         a.v.cmplx_val.imag !=
  393.                         b.v.cmplx_val.imag);
  394.             }
  395.     }
  396.     push(Ginteger(&a,result));
  397. }
  398.  
  399.  
  400. f_gt()
  401. {
  402. struct value a, b;
  403.     register int result;
  404.     (void) pop(&b);
  405.     (void) pop(&a);
  406.     switch(a.type) {
  407.         case INTGR:
  408.             switch (b.type) {
  409.                 case INTGR:
  410.                     result = (a.v.int_val >
  411.                         b.v.int_val);
  412.                     break;
  413.                 case CMPLX:
  414.                     result = (a.v.int_val >
  415.                         b.v.cmplx_val.real);
  416.             }
  417.             break;
  418.         case CMPLX:
  419.             switch (b.type) {
  420.                 case INTGR:
  421.                     result = (a.v.cmplx_val.real >
  422.                         b.v.int_val);
  423.                     break;
  424.                 case CMPLX:
  425.                     result = (a.v.cmplx_val.real >
  426.                         b.v.cmplx_val.real);
  427.             }
  428.     }
  429.     push(Ginteger(&a,result));
  430. }
  431.  
  432.  
  433. f_lt()
  434. {
  435. struct value a, b;
  436.     register int result;
  437.     (void) pop(&b);
  438.     (void) pop(&a);
  439.     switch(a.type) {
  440.         case INTGR:
  441.             switch (b.type) {
  442.                 case INTGR:
  443.                     result = (a.v.int_val <
  444.                         b.v.int_val);
  445.                     break;
  446.                 case CMPLX:
  447.                     result = (a.v.int_val <
  448.                         b.v.cmplx_val.real);
  449.             }
  450.             break;
  451.         case CMPLX:
  452.             switch (b.type) {
  453.                 case INTGR:
  454.                     result = (a.v.cmplx_val.real <
  455.                         b.v.int_val);
  456.                     break;
  457.                 case CMPLX:
  458.                     result = (a.v.cmplx_val.real <
  459.                         b.v.cmplx_val.real);
  460.             }
  461.     }
  462.     push(Ginteger(&a,result));
  463. }
  464.  
  465.  
  466. f_ge()
  467. {
  468. struct value a, b;
  469.     register int result;
  470.     (void) pop(&b);
  471.     (void) pop(&a);
  472.     switch(a.type) {
  473.         case INTGR:
  474.             switch (b.type) {
  475.                 case INTGR:
  476.                     result = (a.v.int_val >=
  477.                         b.v.int_val);
  478.                     break;
  479.                 case CMPLX:
  480.                     result = (a.v.int_val >=
  481.                         b.v.cmplx_val.real);
  482.             }
  483.             break;
  484.         case CMPLX:
  485.             switch (b.type) {
  486.                 case INTGR:
  487.                     result = (a.v.cmplx_val.real >=
  488.                         b.v.int_val);
  489.                     break;
  490.                 case CMPLX:
  491.                     result = (a.v.cmplx_val.real >=
  492.                         b.v.cmplx_val.real);
  493.             }
  494.     }
  495.     push(Ginteger(&a,result));
  496. }
  497.  
  498.  
  499. f_le()
  500. {
  501. struct value a, b;
  502.     register int result;
  503.     (void) pop(&b);
  504.     (void) pop(&a);
  505.     switch(a.type) {
  506.         case INTGR:
  507.             switch (b.type) {
  508.                 case INTGR:
  509.                     result = (a.v.int_val <=
  510.                         b.v.int_val);
  511.                     break;
  512.                 case CMPLX:
  513.                     result = (a.v.int_val <=
  514.                         b.v.cmplx_val.real);
  515.             }
  516.             break;
  517.         case CMPLX:
  518.             switch (b.type) {
  519.                 case INTGR:
  520.                     result = (a.v.cmplx_val.real <=
  521.                         b.v.int_val);
  522.                     break;
  523.                 case CMPLX:
  524.                     result = (a.v.cmplx_val.real <=
  525.                         b.v.cmplx_val.real);
  526.             }
  527.     }
  528.     push(Ginteger(&a,result));
  529. }
  530.  
  531.  
  532. f_plus()
  533. {
  534. struct value a, b, result;
  535.     (void) pop(&b);
  536.     (void) pop(&a);
  537.     switch(a.type) {
  538.         case INTGR:
  539.             switch (b.type) {
  540.                 case INTGR:
  541.                     (void) Ginteger(&result,a.v.int_val +
  542.                         b.v.int_val);
  543.                     break;
  544.                 case CMPLX:
  545.                     (void) Gcomplex(&result,a.v.int_val +
  546.                         b.v.cmplx_val.real,
  547.                        b.v.cmplx_val.imag);
  548.             }
  549.             break;
  550.         case CMPLX:
  551.             switch (b.type) {
  552.                 case INTGR:
  553.                     (void) Gcomplex(&result,b.v.int_val +
  554.                         a.v.cmplx_val.real,
  555.                        a.v.cmplx_val.imag);
  556.                     break;
  557.                 case CMPLX:
  558.                     (void) Gcomplex(&result,a.v.cmplx_val.real+
  559.                         b.v.cmplx_val.real,
  560.                         a.v.cmplx_val.imag+
  561.                         b.v.cmplx_val.imag);
  562.             }
  563.     }
  564.     push(&result);
  565. }
  566.  
  567.  
  568. f_minus()
  569. {
  570. struct value a, b, result;
  571.     (void) pop(&b);
  572.     (void) pop(&a);        /* now do a - b */
  573.     switch(a.type) {
  574.         case INTGR:
  575.             switch (b.type) {
  576.                 case INTGR:
  577.                     (void) Ginteger(&result,a.v.int_val -
  578.                         b.v.int_val);
  579.                     break;
  580.                 case CMPLX:
  581.                     (void) Gcomplex(&result,a.v.int_val -
  582.                         b.v.cmplx_val.real,
  583.                        -b.v.cmplx_val.imag);
  584.             }
  585.             break;
  586.         case CMPLX:
  587.             switch (b.type) {
  588.                 case INTGR:
  589.                     (void) Gcomplex(&result,a.v.cmplx_val.real -
  590.                         b.v.int_val,
  591.                         a.v.cmplx_val.imag);
  592.                     break;
  593.                 case CMPLX:
  594.                     (void) Gcomplex(&result,a.v.cmplx_val.real-
  595.                         b.v.cmplx_val.real,
  596.                         a.v.cmplx_val.imag-
  597.                         b.v.cmplx_val.imag);
  598.             }
  599.     }
  600.     push(&result);
  601. }
  602.  
  603.  
  604. f_mult()
  605. {
  606. struct value a, b, result;
  607.     (void) pop(&b);
  608.     (void) pop(&a);    /* now do a*b */
  609.  
  610.     switch(a.type) {
  611.         case INTGR:
  612.             switch (b.type) {
  613.                 case INTGR:
  614.                     (void) Ginteger(&result,a.v.int_val *
  615.                         b.v.int_val);
  616.                     break;
  617.                 case CMPLX:
  618.                     (void) Gcomplex(&result,a.v.int_val *
  619.                         b.v.cmplx_val.real,
  620.                         a.v.int_val *
  621.                         b.v.cmplx_val.imag);
  622.             }
  623.             break;
  624.         case CMPLX:
  625.             switch (b.type) {
  626.                 case INTGR:
  627.                     (void) Gcomplex(&result,b.v.int_val *
  628.                         a.v.cmplx_val.real,
  629.                         b.v.int_val *
  630.                         a.v.cmplx_val.imag);
  631.                     break;
  632.                 case CMPLX:
  633.                     (void) Gcomplex(&result,a.v.cmplx_val.real*
  634.                         b.v.cmplx_val.real-
  635.                         a.v.cmplx_val.imag*
  636.                         b.v.cmplx_val.imag,
  637.                         a.v.cmplx_val.real*
  638.                         b.v.cmplx_val.imag+
  639.                         a.v.cmplx_val.imag*
  640.                         b.v.cmplx_val.real);
  641.             }
  642.     }
  643.     push(&result);
  644. }
  645.  
  646.  
  647. f_div()
  648. {
  649. struct value a, b, result;
  650. register double square;
  651.     (void) pop(&b);
  652.     (void) pop(&a);    /* now do a/b */
  653.  
  654.     switch(a.type) {
  655.         case INTGR:
  656.             switch (b.type) {
  657.                 case INTGR:
  658.                     if (b.v.int_val)
  659.                       (void) Ginteger(&result,a.v.int_val /
  660.                         b.v.int_val);
  661.                     else {
  662.                       (void) Ginteger(&result,0);
  663.                       undefined = TRUE;
  664.                     }
  665.                     break;
  666.                 case CMPLX:
  667.                     square = b.v.cmplx_val.real*
  668.                         b.v.cmplx_val.real +
  669.                         b.v.cmplx_val.imag*
  670.                         b.v.cmplx_val.imag;
  671.                     if (square)
  672.                         (void) Gcomplex(&result,a.v.int_val*
  673.                         b.v.cmplx_val.real/square,
  674.                         -a.v.int_val*
  675.                         b.v.cmplx_val.imag/square);
  676.                     else {
  677.                         (void) Gcomplex(&result,0.0,0.0);
  678.                         undefined = TRUE;
  679.                     }
  680.             }
  681.             break;
  682.         case CMPLX:
  683.             switch (b.type) {
  684.                 case INTGR:
  685.                     if (b.v.int_val)
  686.                       
  687.                       (void) Gcomplex(&result,a.v.cmplx_val.real/
  688.                         b.v.int_val,
  689.                         a.v.cmplx_val.imag/
  690.                         b.v.int_val);
  691.                     else {
  692.                         (void) Gcomplex(&result,0.0,0.0);
  693.                         undefined = TRUE;
  694.                     }
  695.                     break;
  696.                 case CMPLX:
  697.                     square = b.v.cmplx_val.real*
  698.                         b.v.cmplx_val.real +
  699.                         b.v.cmplx_val.imag*
  700.                         b.v.cmplx_val.imag;
  701.                     if (square)
  702.                     (void) Gcomplex(&result,(a.v.cmplx_val.real*
  703.                         b.v.cmplx_val.real+
  704.                         a.v.cmplx_val.imag*
  705.                         b.v.cmplx_val.imag)/square,
  706.                         (a.v.cmplx_val.imag*
  707.                         b.v.cmplx_val.real-
  708.                         a.v.cmplx_val.real*
  709.                         b.v.cmplx_val.imag)/
  710.                             square);
  711.                     else {
  712.                         (void) Gcomplex(&result,0.0,0.0);
  713.                         undefined = TRUE;
  714.                     }
  715.             }
  716.     }
  717.     push(&result);
  718. }
  719.  
  720.  
  721. f_mod()
  722. {
  723. struct value a, b;
  724.     (void) pop(&b);
  725.     (void) pop(&a);    /* now do a%b */
  726.  
  727.     if (a.type != INTGR || b.type != INTGR)
  728.         int_error("can only mod ints",NO_CARET);
  729.     if (b.v.int_val)
  730.         push(Ginteger(&a,a.v.int_val % b.v.int_val));
  731.     else {
  732.         push(Ginteger(&a,0));
  733.         undefined = TRUE;
  734.     }
  735. }
  736.  
  737.  
  738. f_power()
  739. {
  740. struct value a, b, result;
  741. register int i, t, count;
  742. register double mag, ang;
  743.     (void) pop(&b);
  744.     (void) pop(&a);    /* now find a**b */
  745.  
  746.     switch(a.type) {
  747.         case INTGR:
  748.             switch (b.type) {
  749.                 case INTGR:
  750.                     count = abs(b.v.int_val);
  751.                     t = 1;
  752.                     for(i = 0; i < count; i++)
  753.                         t *= a.v.int_val;
  754.                     if (b.v.int_val >= 0)
  755.                         (void) Ginteger(&result,t);
  756.                     else
  757.                       if (t != 0)
  758.                         (void) Gcomplex(&result,1.0/t,0.0);
  759.                       else {
  760.                          undefined = TRUE;
  761.                          (void) Gcomplex(&result, 0.0, 0.0);
  762.                       }
  763.                     break;
  764.                 case CMPLX:
  765.                     mag =
  766.                       pow(magnitude(&a),fabs(b.v.cmplx_val.real));
  767.                     if (b.v.cmplx_val.real < 0.0)
  768.                       if (mag != 0.0)
  769.                         mag = 1.0/mag;
  770.                       else 
  771.                         undefined = TRUE;
  772.                     mag *= exp(-b.v.cmplx_val.imag*angle(&a));
  773.                     ang = b.v.cmplx_val.real*angle(&a) +
  774.                           b.v.cmplx_val.imag*log(magnitude(&a));
  775.                     (void) Gcomplex(&result,mag*cos(ang),
  776.                         mag*sin(ang));
  777.             }
  778.             break;
  779.         case CMPLX:
  780.             switch (b.type) {
  781.                 case INTGR:
  782.                     if (a.v.cmplx_val.imag == 0.0) {
  783.                         mag = pow(a.v.cmplx_val.real,(double)abs(b.v.int_val));
  784.                         if (b.v.int_val < 0)
  785.                           if (mag != 0.0)
  786.                             mag = 1.0/mag;
  787.                           else 
  788.                             undefined = TRUE;
  789.                         (void) Gcomplex(&result,mag,0.0);
  790.                     }
  791.                     else {
  792.                         /* not so good, but...! */
  793.                         mag = pow(magnitude(&a),(double)abs(b.v.int_val));
  794.                         if (b.v.int_val < 0)
  795.                           if (mag != 0.0)
  796.                             mag = 1.0/mag;
  797.                           else 
  798.                             undefined = TRUE;
  799.                         ang = angle(&a)*b.v.int_val;
  800.                         (void) Gcomplex(&result,mag*cos(ang),
  801.                             mag*sin(ang));
  802.                     }
  803.                     break;
  804.                 case CMPLX:
  805.                     mag = pow(magnitude(&a),fabs(b.v.cmplx_val.real));
  806.                     if (b.v.cmplx_val.real < 0.0)
  807.                       if (mag != 0.0)
  808.                         mag = 1.0/mag;
  809.                       else 
  810.                         undefined = TRUE;
  811.                     mag *= exp(-b.v.cmplx_val.imag*angle(&a));
  812.                     ang = b.v.cmplx_val.real*angle(&a) +
  813.                           b.v.cmplx_val.imag*log(magnitude(&a));
  814.                     (void) Gcomplex(&result,mag*cos(ang),
  815.                         mag*sin(ang));
  816.             }
  817.     }
  818.     push(&result);
  819. }
  820.  
  821.  
  822. f_factorial()
  823. {
  824. struct value a;
  825. register int i;
  826. register double val;
  827.  
  828.     (void) pop(&a);    /* find a! (factorial) */
  829.  
  830.     switch (a.type) {
  831.         case INTGR:
  832.             val = 1.0;
  833.             for (i = a.v.int_val; i > 1; i--)  /*fpe's should catch overflows*/
  834.                 val *= i;
  835.             break;
  836.         default:
  837.             int_error("factorial (!) argument must be an integer",
  838.             NO_CARET);
  839.         }
  840.  
  841.     push(Gcomplex(&a,val,0.0));
  842.             
  843. }
  844.  
  845.  
  846. int
  847. f_jump(x)
  848. union argument *x;
  849. {
  850.     return(x->j_arg);
  851. }
  852.  
  853.  
  854. int
  855. f_jumpz(x)
  856. union argument *x;
  857. {
  858. struct value a;
  859.     int_check(&top_of_stack);
  860.     if (top_of_stack.v.int_val) {    /* non-zero */
  861.         (void) pop(&a);
  862.         return 1;                /* no jump */
  863.     }
  864.     else
  865.         return(x->j_arg);        /* leave the argument on TOS */
  866. }
  867.  
  868.  
  869. int
  870. f_jumpnz(x)
  871. union argument *x;
  872. {
  873. struct value a;
  874.     int_check(&top_of_stack);
  875.     if (top_of_stack.v.int_val)    /* non-zero */
  876.         return(x->j_arg);        /* leave the argument on TOS */
  877.     else {
  878.         (void) pop(&a);
  879.         return 1;                /* no jump */
  880.     }
  881. }
  882.  
  883.  
  884. int
  885. f_jtern(x)
  886. union argument *x;
  887. {
  888. struct value a;
  889.  
  890.     int_check(pop(&a));
  891.     if (a.v.int_val)
  892.         return(1);                /* no jump; fall through to TRUE code */
  893.     else
  894.         return(x->j_arg);        /* go jump to FALSE code */
  895. }
  896.